﻿#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QDomDocument>
#include <QDomElement>
#include <QDomNode>
#include <QDomProcessingInstruction>
#include <QList>
#include <QString>
#include <QStringList>
#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QMessageBox>
#include <QEvent>
#include <QMouseEvent>
#include <QProcess>
#include <iostream>
#include <string>
#include <QDebug>
#include <QMap>
#include "initcreathtml.h"
using namespace std;

//定义模板
template<typename T>
inline T const& compareTwo(T const &a, T const &b)
{
    return a>b?a:b;
}
template<typename T>
inline T const& compareThree(T const &a, T const &b, T const &c)
{
    return compareTwo(compareTwo(a, b),c);
}
template<typename T>
inline T const& compareFour(T const &a, T const &b, T const &c,T const &d)
{
    return compareTwo(compareTwo(compareTwo(a, b),c),d);
}
//需要解析的xml数据类型
class XMLFile;
class XMLMsg;
namespace Ui {
class Widget;
}
typedef QList<XMLFile> XMLFileList;
typedef QList<XMLMsg> MsgList;
class XMLMsg
{
public:
    bool      m_needMAC;
    QString   m_strId;
    XMLFileList m_reqFieldList;
    XMLFileList m_respFieldList;
    XMLMsg(const QString& strId = "",
            const bool needMAC = false ):
            m_strId( strId ),
            m_needMAC( needMAC ){}
    bool operator==(const XMLMsg& it)
    {
        return (m_strId == it.m_strId);
    }
};

class XMLFile
{
public:
    QString m_strFlag;
    QString m_strId;
    QString m_tagName;
    QString m_strValue;
    QString m_strRequestPath;
    QString m_strResponsePath;
    QString m_strRemark;
    XMLFile(const QString &strFlag ="",
            const QString &strId  = "",
            const QString &tagName = "",
            const QString &strVal = "",
            const QString &strRequestPath = "",
            const QString &strResponsePath = "",
            const QString &strRemark =""):
        m_strFlag( strFlag),
        m_strId( strId ),
        m_tagName( tagName ),
        m_strValue( strVal ),
        m_strRequestPath( strRequestPath ),
        m_strResponsePath( strResponsePath ),
        m_strRemark ( strRemark ){}
    bool operator ==(const XMLFile& XMLID)
    {
        return (m_strId == XMLID.m_strId);
    }

};
typedef struct msgField{
    QString m_strTagName;
    QString m_strRequestPath;
    QString m_strResponsePath;
    QString m_strValue;
    QString m_strRemark;
    msgField(const QString &tagName ="",
             const QString &strRequestPath ="",
             const QString &strResponsePath ="",
             const QString &strValue ="",
             const QString &strRemark =""
            ):m_strTagName(tagName),
        m_strRequestPath(strRequestPath),
        m_strResponsePath(strResponsePath),
        m_strValue(strValue),
        m_strRemark(strRemark)
    {}


}FieldGather;

typedef struct TransDefRV{
    QString m_remark;
    QString m_value;
}TransDef_RV;

typedef  QList<FieldGather> FieldGatherList;
typedef  QMap<QString,QString> FieldMap;

typedef QMap<QString,TransDef_RV> TransDefMap;
typedef QMap<QString,int> RepeatMap;

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    //APP Start
    void initApp();
    //get desktop
    void getDesktopPath();
    //page1 tips
    void initPage1Placeholder();
    //page2 tips
    void initPage2Placeholder(QString &arg =QString("SST"));
    //page3 tips
    void initPage3Placeholder();
    //page 2 comboBox 下拉框初始化
    void initPage2ComboBox();
    //事件分发
    void bindConnect();
    //Filter install
    void installAppFilter();
    //set Icon
    void setMyWindIcon();
    //读取新交易配置报文的资源
    void checkTargetSaveFile();
    //读取现有的msg配置
    void ReadMsg(const QString &filePath, const QString &msgID, const QString &AppID);
    //解析节点
    QDomElement& ParseNode(const QDomElement &root,const QString &msgID, const QString &AppID,int arg);
    //创建标准xml 头
    void createXML(QString &filePath);
    //追加 xml标签
    void appendXML(QString &filePath,XMLFileList &fileList,QString &msgID,QString &msgName,QString &Mac);
    //创建二级标签
    void CreateSecondNode(QDomDocument &doc,QDomElement &root,XMLFileList &fileList);
    //将读取的数据保存到map里
    void ReadLabelAndRemarktoSaveDate(XMLFileList &Mylist,FieldMap &MyMap, int &len);
    //事件过滤器
    bool eventFilter(QObject *obj, QEvent *e);
    //读/写文件
    void ReadFieldAndSaveToData(QString &chanelType);
    //新文件创建xml头
    void CreateXmlHeadAndBody(QString &targetFile,QString &strXmlHead,QString &findKey);
    //插入头的内容
    void CreateFileBodyXml(QString &filePath,QString &strXmlHead =QString(""));
    //map msg数据插入前预处理
    void MapToPrepareData(QString &msgLabel,QString &chanelType,QString &AppID,QString &msgID,QString &tranCodeName);
    //生成 msg xml
    void DataTransformMsgXML(QString &msgID,QString &tranCodeName,QString &targetFile,QString &chanelType,QString &AppID =QString(""));
    //生成 transDef xml
    void DataTransformDefXML(QString &msgID,QString &tranCodeName,QString &filePath,int len);
    //map def数据插入前预处理 1. map key to targetLabel; 2. Map value to Remark
    void MapToPrepareDataDef(FieldMap &myFieldMap,QString &xml,int len);
    //追加标签
    void AppendLabel(QString &filePath, QString &msgLabel,QString &findKey);
    // 将文本插入 xml标签内
    void insertXmlContext(QString &filePath,QString &xmlHead,QString &text,QString &findKey);

    //读取map中的数据格式化Cols 的TransDef
    void mapFormatTransDefColsBody(TransDefMap &myMap,QString &strformat, int &maxFeildLen);

    //先读文件
    void ReadXmltoMap(const QString &strFilePath,TransDefMap &myMap,int &maxFeildLen);
    //写文件
    void WriteTransDefXml(QString &strFilePath,TransDefMap &myMap,int &maxFeildLen);
    void ClearTransDefRepeat(QString &filePath);
    //数字大小比较 功能函数
    int fillBlankSpace(int arg1,int arg2);
    //去掉最后的/ 或者文件名
    void findOpenFilePath(QString &src, QString &dest);
    //检查msgId是否重复
    bool DocumentAttributeExists(QString &filePath,QString &MsgID);
    //通过配置文件设置IDE的路径
    void SetIDEPath(int index);
signals:
    //鼠标双击事件
    void dblMouseButtonSignal(QString arg);

private slots:


    void on_buttonFile_clicked();

    void on_buttonTransMsg_clicked();

    void on_buttonTransdef_clicked();

    void on_buttonTest_clicked();

    void on_ShowInitCreateHtmlLog(QString arg);

    void on_buttonMsg_clicked();

    void on_buttonTransDef_clicked();

    void on_buttonClearRepeat_clicked();

    void on_comboxChannelType_currentIndexChanged(const QString &arg1);

    void on_comboBoxEdit_currentIndexChanged(int index);

private:
    Ui::Widget *ui;
    XMLFileList m_XMLList;              //保存一行标签的容器
    XMLFile m_XMLRoot;                 //保存一支交易msg标签的容器
    QString m_AppID;                   //APPid
    QString m_msgID;                   //交易码
    QString m_MAC;                     //是否开启mac
    FieldGather m_Field;               //保存一行标签的容器
    FieldGatherList m_FieldGatherList; //保存一支交易的标签容器
    int m_resNum;                   //请求报文的request的个数
    int m_resRemarkNum;             //请求报文的Remark的个数
    int m_respNum;                  //响应报文的Response标签个数
    int m_respRemarkNum;            //响应报文的Remark的个数
    int m_resTagLenMax;             //响应的F_TagName报文的最长字段
    int m_respTagLenMax;            //响应报文的最长字段
    FieldMap m_FieldMap;            //将新交易P 和RP 保存
    int m_TrandataDefLen;           //transDef 字段最长的一个
    QString m_tempDir;              //创建桌面的路径
    InitCreatHtml *m_CreateHtml;    //网页的实例对象
    QString m_OpenPath;             //鼠标双击打开的文件夹路径或者文件名路径
    QString m_OpenOtherEdit;        //第三方工具的名称，或安装路径
    QString m_OpenEditOtherName;    //第三方工具名称
    TransDefMap m_dataMap;          //保存新交易的请求报文和响应报文的结构体
    int m_RecordNum;                //记录不重复的label个数
    int m_TransDefFeildLen;         //保存最大的字段长度
    QString m_strChannelType;       //渠道号
    RepeatMap m_repeatMap;
    QString m_xmlRootTag;       //去除重复标签使用的Tag
    QString m_xmlRootRemark;    //去除重复标签使用的remark

};

#endif // WIDGET_H
